package com.jiahe.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiahe.blog.dao.ArticleDao;
import com.jiahe.blog.dao.ArticleTagDao;
import com.jiahe.blog.dao.CategoryDao;
import com.jiahe.blog.dao.TagDao;
import com.jiahe.blog.entity.ArticleEntity;
import com.jiahe.blog.entity.ArticleTagEntity;
import com.jiahe.blog.model.dto.ArticleBackDTO;
import com.jiahe.blog.model.dto.PageDTO;
import com.jiahe.blog.model.vo.ArticleVO;
import com.jiahe.blog.model.vo.ConditionVO;
import com.jiahe.blog.service.ArticleService;
import com.jiahe.blog.service.ArticleTagService;
import com.jiahe.blog.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.jiahe.blog.model.BlogConst.FALSE;
import static com.jiahe.blog.model.RedisPrefixConst.ARTICLE_LIKE_COUNT;
import static com.jiahe.blog.model.RedisPrefixConst.ARTICLE_VIEWS_COUNT;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleDao, ArticleEntity> implements ArticleService {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private ArticleTagService articleTagService;

    @Autowired
    private ArticleDao articleDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private ArticleTagDao articleTagDao;

    @Autowired
    private TagDao tagDao;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdateArticle(ArticleVO articleVO) {
        //保存或者修改文章
        ArticleEntity articleEntity = ArticleEntity.builder()
                .id(articleVO.getId())
                .userId(UserUtils.getLoginUser().getUserInfoId())
                .categoryId(articleVO.getCategoryId())
                .articleCover(articleVO.getArticleCover())
                .articleTitle(articleVO.getArticleTitle())
                .articleContent(articleVO.getArticleContent())
                .createTime(Objects.isNull(articleVO.getId()) ? new Date() : null)
                .updateTime(Objects.nonNull(articleVO.getId()) ? new Date() : null)
                .top(articleVO.getTop())
                .draft(articleVO.getDraft())
                .build();
        this.saveOrUpdate(articleEntity);
        // 编辑文章则删除文章所有标签
        if (Objects.nonNull(articleVO.getId()) && articleVO.getDraft().equals(FALSE)) {
            articleTagDao.delete(new LambdaQueryWrapper<ArticleTagEntity>().eq(ArticleTagEntity::getArticleId, articleVO.getId()));
        }
        // 添加文章标签
        if (!articleVO.getTagIdList().isEmpty()) {
            List<ArticleTagEntity> articleTagList = articleVO.getTagIdList().stream().map(tagId -> ArticleTagEntity.builder()
                    .articleId(articleEntity.getId())
                    .tagId(tagId)
                    .build())
                    .collect(Collectors.toList());
            articleTagService.saveBatch(articleTagList);
        }
    }

    @Override
    public PageDTO<ArticleBackDTO> listArticleBackDTO(ConditionVO conditionVO) {
        // 转换页码
        conditionVO.setCurrent((conditionVO.getCurrent()-1) * conditionVO.getSize());
        // 查询文章总量
        Integer count = articleDao.countUserArticleBacks(conditionVO);
        if (count == 0) {
            return new PageDTO<>();
        }
        // 查询后台文章
        List<ArticleBackDTO> articleBackList = articleDao.listUserArticleBacks(conditionVO);
        // 查询文章点赞量和浏览量
        Map<Object, Object> viewsCountMap = redisTemplate.boundHashOps(ARTICLE_VIEWS_COUNT).entries();
        Map<Object, Object> likeCountMap = redisTemplate.boundHashOps(ARTICLE_LIKE_COUNT).entries();
        // 封装点赞量和浏览量
        articleBackList.forEach(item -> {
            item.setViewsCount((Integer) Objects.requireNonNull(viewsCountMap, "浏览量为空").get(item.getId().toString()));
            item.setLikeCount((Integer) Objects.requireNonNull(likeCountMap, "点赞量为空").get(item.getId().toString()));
        });
        return new PageDTO<>(articleBackList, count);
    }
}
